﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Text.RegularExpressions;

namespace KPAR
{
    public static class Resolver
    {
        private static List<string> pronounTypes = new List<string>(new string[] { "WP$", "WP", "PP", "PP$" });

        private static List<string> definiteArticles = new List<string>(new string[] { "the", "this", "that", "these", "those", 
                                                            "my", "your", "his", "her", "its", "our", "your", "their" });

        private static List<string> indefiniteArticles = new List<string>(new string[] { "a", "an", "other", "another" });

        private static List<string> domainConcepts = new List<string>(new string[] { "system", "technology", "expert", "printer" });

        private static List<string> preferringVCs = new List<string>(new string[] { "discuss", "present", "illustrate", 
                                                        "summarise", "examine", "describe", "define", "show", 
                                                        "check", "develop", "review", "report", "outline", 
                                                        "consider", "investigate", "explore", "assess", "analyse", 
                                                        "synthesise", "study", "survey", "deal", "cover" });

        private static List<string> preferringNPs = new List<string>(new string[] { "chapter", "section", "table" });

        private static List<string> clauseLimiterTypes = new List<string>(new string[] { "WP$", "WP", "WRB", "WDT", "CC" });

        public static void Run()
        {
            XElement doc = XElement.Load(@"C:\Users\Christopher\Desktop\chunked_testlauf.xml");

            #region AusgabeStart
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("KPAR-AUSGABE");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("Es folgen die gefundenen Pronomen, die aufgelöst werden sollen:");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------"); 
            #endregion

            IEnumerable<XElement> pronouns =
                from pronoun in doc.Descendants("token")
                where pronounTypes.Contains(pronoun.Attribute("pos").Value)
                select pronoun;

            foreach (XElement pronoun in pronouns)
            {

                #region MetadatenPronomen
                XElement metaData = new XElement("meta");

                string[] pronounID = pronoun.Parent.Attribute("id").Value.Split(new char[] { ':' });
                int pronID_Int = Int32.Parse(pronounID.Last());

                string pronNumber = pronoun.Parent.Attribute("number").Value;

                IEnumerable<XElement> headings =
                    from heading in doc.Descendants("heading")
                    where heading.Attribute("id").Value.StartsWith(pronounID[0])
                    select heading;

                IEnumerable<XElement> relevantParagraph =
                    from paragraph in doc.Descendants("paragraph")
                    where paragraph.Attribute("id").Value.Equals(String.Join(":", pronounID, 0, 2))
                    select paragraph;

                List<string> sentenceIDs = new List<string>();
                int PronounSentID_Int = Int32.Parse(pronounID[2]);

                for (int i = PronounSentID_Int; (i > 0 && i >= PronounSentID_Int - 2); i--)
                    sentenceIDs.Add("" + i);

                IEnumerable<XElement> sentences =
                    from sentence in doc.Descendants("sentence")
                    let sentID = sentence.Attribute("id").Value.Split(new char[] { ':' }).Last()
                    where sentenceIDs.Contains(sentID)
                    select sentence;

                IEnumerable<XElement> nouns =
                    from noun in sentences.Descendants("NC")
                    let nounID = Int32.Parse(noun.Attribute("id").Value.Split(new char[] { ':' }).Last())
                    where nounID < pronID_Int
                    select noun;

                IEnumerable<XElement> candidates = nouns;

                //Console.WriteLine(pronNumber);

                if (!pronNumber.Equals("indisc"))
                {
                    //Console.WriteLine("lalala");
                    //candidates =
                    //    from noun in sentences.Descendants("NC")
                    //    let nounID = Int32.Parse(noun.Attribute("id").Value.Split(new char[] { ':' }).Last())
                    //    where nounID < pronID_Int
                    //    select noun;
                    candidates =
                        from noun in candidates
                        where noun.Attribute("number").Value.Equals(pronNumber) || noun.Attribute("number").Value.Equals("indisc")
                        select noun;           
                }
                else
                {
                    //Console.WriteLine("abcabc");
                        //candidates =
                        //    from noun in sentences.Descendants("NC")
                        //    where noun.Attribute("number").Value.Equals(pronNumber) || noun.Attribute("number").Value.Equals("indisc")
                        //    select noun;                    
                }

                //foreach (XElement candidate in candidates)
                //    Console.WriteLine(candidate);

                //if (pronNumber.Equals("inidisc"))
                //{
                //    candidates =
                //        from noun in sentences.Descendants("NC")
                //        let nounID = Int32.Parse(noun.Attribute("id").Value.Split(new char[] { ':' }).Last())
                //        where nounID < pronID_Int
                //        select noun;
                //}
                //else
                //{

                //}

                List<Candidate> candidateNouns = new List<Candidate>();

                metaData.Add(new XElement("headings", headings));
                metaData.Add(relevantParagraph.First());
                metaData.Add(new XElement("sentences", sentences));
                metaData.Add(new XElement("nouns", nouns)); 
                #endregion

                //hier kommt alles rein, was für die Auswertung jedes Pronomen gebraucht wird:
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                #region AuswertungNotwendigkeitenPronomen

                XElement precedingElemPron = pronoun.Parent.ElementsBeforeSelf().LastOrDefault();
                XElement nextElemPron = pronoun.Parent.ElementsAfterSelf().FirstOrDefault();

                XElement precedingVC_Pron =
                    (precedingElemPron != null && precedingElemPron.Name == "VC") ?
                        precedingElemPron : null;   
                XElement nextVC_Pron = 
                    (nextElemPron != null && nextElemPron.Name == "VC") ? 
                        nextElemPron : null;

                string collocVC_PrePron = null;
                string collocVC_PostPron = null;

                if (precedingVC_Pron != null)
                {
                    XElement lastTokenOfVC_PrePron =
                        (from token in precedingVC_Pron.Descendants("token")
                         where token.Attribute("pos").Value.StartsWith("V")
                         select token).LastOrDefault();
                    if (lastTokenOfVC_PrePron != null)
                    {
                        collocVC_PrePron = lastTokenOfVC_PrePron.Attribute("lemma").Value;
                    }
                }
                if (nextVC_Pron != null)
                {
                    XElement lastTokenOfVC_PostPron =
                        (from token in nextVC_Pron.Descendants("token")
                         where token.Attribute("pos").Value.StartsWith("V")
                         select token).LastOrDefault();
                    if (lastTokenOfVC_PostPron != null)
                    {
                        collocVC_PostPron = lastTokenOfVC_PostPron.Attribute("lemma").Value;
                    }
                }

                string pronSentID = String.Join(":", pronounID, 0, 3);
                int pronSentID_Int = Int32.Parse(pronSentID.Split(new char[] { ':' }).Last());

                XElement pronCurrentSent =
                    (from sentence in sentences
                     where sentence.Attribute("id").Value.Equals(pronSentID)
                     select sentence).First();

                #region IRVerzweigungen
		        int countVC = 0;

                XElement PreviousElements = new XElement("PreviousElements");
                List<string> ImmediateReferencePOSList = new List<string>();

                foreach (XNode n in pronCurrentSent.Nodes())
                {
                    if (n is XElement)
                    {
                        XElement nAsXElem = (XElement) n;
                        XElement lastToken = nAsXElem.Descendants("token").LastOrDefault();

                        string nodeID = nAsXElem.Attribute("id").Value.Split(new char[] { ':' }).Last();

                        bool nIsToken = (lastToken == null);
                        bool isPrevElem = Int32.Parse(nodeID) < pronID_Int;

                        if (nIsToken)
                        {
                            string nodePOS = nAsXElem.Attribute("pos").Value;

                            if (isPrevElem)
                            {
                                if (clauseLimiterTypes.Contains(nodePOS))
                                {
                                    PreviousElements.AddFirst(nAsXElem);
                                }
                                if (nodePOS.StartsWith("IN") &&
                                        nAsXElem.Attribute("prepositional").Value == "False")
                                {
                                    ImmediateReferencePOSList.Add("CC");
                                    PreviousElements.AddFirst(nAsXElem);
                                }
                                else
                                {
                                    ImmediateReferencePOSList.Add(nodePOS);
                                }
                            }
                        }
                        else
                        {
                            if (nAsXElem.Name == "VC")
                                countVC++;
                            if (isPrevElem)
                            {
                                string POSListString = nAsXElem.Name.ToString();
                                if (clauseLimiterTypes.Contains(lastToken.Attribute("pos").Value))
                                    PreviousElements.AddFirst(nAsXElem);
                                if (nAsXElem.Name == "NC")
                                {
                                    if (nAsXElem.Descendants().Count() == 1)
                                    {
                                        XElement potentialPron = nAsXElem.Descendants().First();
                                        if (pronounTypes.Contains(potentialPron.Attribute("pos").Value) &&
                                                potentialPron.Attribute("lemma").Value == "you")
                                        {
                                            POSListString = "you";
                                        }
                                        else
                                        {
                                            POSListString += ":" + nodeID;
                                        }
                                    }
                                    else
                                    {
                                        POSListString += ":" + nodeID;
                                    }
                                }
                                else if (nAsXElem.Name == "VC")
                                {
                                    if (nAsXElem.Descendants("token").First().Attribute("pos").Value == "CC")
                                    {
                                        ImmediateReferencePOSList.Add("CC");
                                    }
                                }
                                ImmediateReferencePOSList.Add(POSListString);
                            }
                        }
                    }
                }

                IEnumerable<XElement> clauseInfos =
                    from info in PreviousElements.Elements()
                    select info;

                int clauseEnd = -1;
                int clauseStart = -1;

                if (countVC > 1 && clauseInfos.Count() > 0)
                {
                    int skippedVCs_CE = 0;
                    int skippedVCs_CS = 0;

                    foreach (XElement clauseInfo in clauseInfos)
                    {
                        int clauseInfoPartID = Int32.Parse(clauseInfo.Attribute("id").Value.Split(new char[] { ':' }).Last());

                        if (clauseEnd == -1)
                        {
                            if (clauseInfo.Name != "VC")
                            {
                                clauseEnd = clauseInfoPartID;
                            }
                            else
                            {
                                if (++skippedVCs_CE == 2)
                                {
                                    clauseEnd = clauseInfoPartID;
                                }
                            }
                        }
                        else if (clauseStart == -1)
                        {
                            if (clauseInfo.Name != "VC")
                            {
                                clauseStart = clauseInfoPartID;
                            }
                            else
                            {
                                if (++skippedVCs_CS == 2)
                                {
                                    clauseStart = clauseInfoPartID;
                                }
                            }
                        }
                    }
                }

                ImmediateReferencePOSList.Reverse();
                //Console.WriteLine(String.Join("_", ImmediateReferencePOSList));

                bool matchedIR = false;
                int foundNCforIR = -1;

                if (String.Join("_", ImmediateReferencePOSList).StartsWith("VC_you_CC") || String.Join("_", ImmediateReferencePOSList).StartsWith("VC_CC"))
                {
                    bool foundConjunction = false;

                    foreach (string listElem in ImmediateReferencePOSList)
                    {
                        //Console.WriteLine(listElem);
                        if (listElem.StartsWith("CC"))
                            foundConjunction = true;
                        else if (foundConjunction)
                        {
                            if (listElem.StartsWith("CC"))
                                break;
                            else if (listElem.StartsWith("VC"))
                            {
                                if (foundNCforIR > 0)
                                {
                                    matchedIR = true;
                                    //Console.WriteLine(foundNCforIR);
                                }
                                break;
                            }
                            else if (listElem.StartsWith("NC"))
                            {
                                if (foundNCforIR > 0)
                                    break;
                                else
                                    foundNCforIR = Int32.Parse(listElem.Split(new char[] { ':' }).Last());

                            }
                            else
                            {
                                if (foundNCforIR > 0)
                                    break;
                            }
                        }
                    }
                } 
	            #endregion

                IEnumerable<string> stringsOfParNCsIE =
                    from NC in relevantParagraph.Descendants("NC")
                    let stringOfNC =
                        String.Join(" ", (from token in NC.Descendants("token")
                                          where token.Attribute("pos").Value.StartsWith("N")
                                          select token.Value))
                    let headNounString = (from token in NC.Descendants("token")
                                          where token.Attribute("pos").Value.StartsWith("N")
                                          select token.Attribute("lemma").Value).LastOrDefault()
                    where !stringOfNC.Equals("") && !headNounString.Equals("")
                    select stringOfNC + ":" + headNounString;

                IEnumerable<string> stringsOfHeadNCsIE =
                    from NC in headings.Descendants("NC")
                    let stringOfNC =
                        String.Join(" ", (from token in NC.Descendants("token")
                                          where token.Attribute("pos").Value.StartsWith("N")
                                          select token.Value))
                    let headNounString = (from token in NC.Descendants("token")
                                          where token.Attribute("pos").Value.StartsWith("N")
                                          select token.Attribute("lemma").Value).LastOrDefault()
                    where !stringOfNC.Equals("") && !headNounString.Equals("")
                    select stringOfNC + ":" + headNounString;

                //Console.WriteLine(String.Join(";", stringsOfHeadNCsIE));

                //List<string> stringsOfParNCs = String.Join(";", stringsOfParNCsIE).Split(new char[] { ';' }).ToList();
                //Console.WriteLine(String.Join(";", stringsOfParNCsIE));

                #region FocusedNPs
		        List<string> focusedNPs = new List<string>();

                foreach (XElement sentence in sentences)
                {
                    List<string> sentenceElementList = new List<string>();

                    foreach (XNode node in sentence.Nodes())
                    {
                        if (node is XElement)
                        {
                            XElement nodeAsXElem = (XElement)node;
                            XElement lastTokenOfNode = nodeAsXElem.Descendants("token").LastOrDefault();

                            string nodeID = nodeAsXElem.Attribute("id").Value.Split(new char[] { ':' }).Last();

                            bool nodeIsToken = (lastTokenOfNode == null);

                            if (nodeIsToken)
                            {
                                sentenceElementList.Add(nodeAsXElem.Attribute("pos").Value);
                            }
                            else
                            {
                                //string lastTokenOfNodeID = lastTokenOfNode.Attribute("id").Value.Split(new char[] { ':' }).Last();
                                string POSListString = nodeAsXElem.Name.ToString();

                                bool foundCleftStarter = false;

                                if (nodeAsXElem.Name == "NC")
                                {
                                    if (nodeAsXElem.Descendants().Count() == 1)
                                    {
                                        if (pronounTypes.Contains(nodeAsXElem.Descendants().First().Attribute("pos").Value))
                                        {
                                            if (nodeAsXElem.Descendants().First().Attribute("lemma").Value == "it")
                                            {
                                                POSListString = "it";
                                                foundCleftStarter = true;
                                            }
                                            else if (nodeAsXElem.Descendants().First().Attribute("lemma").Value == "What")
                                            {
                                                POSListString = "What";
                                                foundCleftStarter = true;
                                            }
                                        }
                                    }
                                    if (!foundCleftStarter)
                                    {
                                        POSListString += ":" + nodeID;
                                    }
                                }
                                else if (nodeAsXElem.Name == "VC")
                                {
                                    if (nodeAsXElem.Descendants("token").Last().Attribute("lemma").Value == "be")
                                    {
                                        POSListString = "be";
                                    }
                                }
                                else if (nodeAsXElem.Name == "PC")
                                {
                                    XElement embeddedNC = nodeAsXElem.Descendants("NC").FirstOrDefault();
                                    if (embeddedNC != null)
                                    {
                                        POSListString = "PC:NC:" + nodeID;
                                    }
                                }
                                sentenceElementList.Add(POSListString);
                            }
                        }
                    }

                    string stringToMatch = String.Join("_", sentenceElementList);
                    //Console.WriteLine(stringToMatch);

                    Match whatCleftmMatch = Regex.Match(stringToMatch, @"^What_NC:[0-9]+_VC(_PC)?_be_NC:([0-9]+)", RegexOptions.IgnoreCase);
                    Match ItCleftmMatch = Regex.Match(stringToMatch, @"^it_be_(PC:)?NC:([0-9]+)", RegexOptions.IgnoreCase);
                    Match PromptMatch = Regex.Match(stringToMatch, @"^([A-Z]*)_?(PC:)?NC:([0-9]+)_,", RegexOptions.IgnoreCase);

                    if (whatCleftmMatch.Success)
                    {
                        focusedNPs.Add(whatCleftmMatch.Groups[2].Value);
                        //Console.WriteLine(whatCleftmMatch.Groups[2].Value);
                    }
                    if (ItCleftmMatch.Success)
                    {
                        focusedNPs.Add(ItCleftmMatch.Groups[2].Value);
                        //Console.WriteLine(ItCleftmMatch.Groups[2].Value);
                    }
                    if (PromptMatch.Success)
                    {
                        focusedNPs.Add(PromptMatch.Groups[3].Value);
                        //Console.WriteLine(PromptMatch.Groups[3].Value);
                    }
                } 
	            #endregion

                #endregion
                /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                Console.WriteLine(pronoun.Parent);
                Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
                Console.WriteLine("Es folgen die Auswertungen für das gefundene Pronomen:");

                foreach (XElement candidate in candidates)
                {
                    //hier kommt alles rein, was für die Auswertung jeden Kandidaten gebraucht wird:
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    #region AuswertungNotwendigkeitenKandidat

                    int[] indicators = new int[13];
                    InitIntArray(indicators);

                    string candID = candidate.Attribute("id").Value;
                    int candID_Int = Int32.Parse(candID.Split(new char[] { ':' }).Last());
                    string candSentID = String.Join(":", candID.Split(new char[] { ':' }), 0, 3);
                    int candSentID_Int = Int32.Parse(candSentID.Split(new char[] { ':' }).Last());

                    XElement candCurrentSent =
                        (from sentence in sentences
                         where sentence.Attribute("id").Value.Equals(candSentID)
                         select sentence).First();

                    string currSentFirstNP_ID = candCurrentSent.Descendants("NC").First().Attribute("id").Value;

                    IEnumerable<XElement> determiners =
                        from determiner in candidate.Descendants("token")
                        where determiner.Attribute("pos").Value.Equals("DT")
                        select determiner;

                    string stringOfNC_Cand = String.Join(" ", 
                        (from token in candidate.Descendants("token")
                         where token.Attribute("pos").Value.StartsWith("N")
                         select token.Value));

                    IEnumerable<string> stringsOfNCParts_Cand =
                        from token in candidate.Descendants("token")
                        where token.Attribute("pos").Value.StartsWith("N")
                        select token.Attribute("lemma").Value;

                    string headNounCand = stringsOfNCParts_Cand.LastOrDefault();

                    //IEnumerable<string> vcSelectedNPs =
                    //    from VC in sentences.Descendants("VC")
                    //    let nextNC = VC.ElementsAfterSelf("NC").FirstOrDefault()
                    //    //lastTokenOfVC
                    //    let lemmaOfVC = VC.Descendants("token").Last().Attribute("lemma").Value
                    //    where nextNC != null && preferringVCs.Contains(lemmaOfVC)
                    //    select nextNC.Attribute("id").Value;

                    //IEnumerable<string> ncSelectedNPs =
                    //    from VC in sentences.Descendants("VC")
                    //    let nextNC = VC.ElementsAfterSelf("NC").FirstOrDefault()
                    //    let precedingNC = VC.ElementsBeforeSelf("NC").LastOrDefault()
                    //    let lemmaOfPrecNC = precedingNC.Descendants("token").Last().Attribute("lemma").Value
                    //    where (nextNC != null && precedingNC != null) && preferringNPs.Contains(lemmaOfPrecNC)
                    //    select nextNC.Attribute("id").Value;

                    int reiterationCount = 0;
                    bool containedInHeadHeadNCs = false;
                    bool matchesDomainConcepts = false;

                    if (headNounCand != null)
                    {
                        foreach (string stringOfParNC in stringsOfParNCsIE)
                        {
                            if ((stringOfParNC.ToLower().Contains(headNounCand.ToLower())) ||
                                (stringOfParNC.ToLower().Contains(stringOfNC_Cand.ToLower())))
                            {
                                reiterationCount++;
                            }
                        }
                        foreach (string stringOfHeadNC in stringsOfHeadNCsIE)
                        {
                            if ((stringOfHeadNC.ToLower().Contains(headNounCand.ToLower())) ||
                                (stringOfHeadNC.ToLower().Contains(stringOfNC_Cand.ToLower())))
                            {
                                containedInHeadHeadNCs = true;
                                break;
                            }
                        }
                        foreach (string domainConcept in domainConcepts)
                        {
                            if ((domainConcept.ToLower().Contains(headNounCand.ToLower())) ||
                                (domainConcept.ToLower().Contains(stringOfNC_Cand.ToLower())))
                            {
                                matchesDomainConcepts = true;
                                break;
                            }
                        }
                    }

                    bool successfulCollocPreference = false;

                    if (collocVC_PrePron != null || collocVC_PostPron != null)
                    {
                        XElement nextElemNoun = candidate.ElementsAfterSelf().FirstOrDefault();
                        XElement precElemNoun = candidate.ElementsBeforeSelf().LastOrDefault();
                        
                        XElement precVC_Noun =
                            (precElemNoun != null && precElemNoun.Name == "VC") ?
                                precElemNoun : null;
                        XElement nextVC_Noun =
                            (nextElemNoun != null && nextElemNoun.Name == "VC") ?
                                nextElemNoun : null;
                        
                        string collocVC_PreNoun = null;
                        string collocVC_PostNoun = null;

                        if (precVC_Noun != null)
                        {
                            XElement lastTokenOfVC_PreNoun =
                                (from token in precVC_Noun.Descendants("token")
                                 where token.Attribute("pos").Value.StartsWith("V")
                                 select token).LastOrDefault();
                            if (lastTokenOfVC_PreNoun != null)
                            {
                                collocVC_PreNoun = lastTokenOfVC_PreNoun.Attribute("lemma").Value;
                                //Console.WriteLine(collocVC_PreNoun);
                                //Console.WriteLine(collocVC_PrePron);

                                if (String.Compare(collocVC_PrePron, collocVC_PreNoun, true) == 0)
                                {
                                    successfulCollocPreference = true;
                                }
                            }
                        }
                        //{
                        //    collocVC_PreNoun = precVC_Noun.Descendants("token").Last().Attribute("lemma").Value;
                        //    Console.WriteLine(collocVC_PreNoun);
                        //    Console.WriteLine(collocVC_PrePron);
                        //    if (String.Compare(collocVC_PrePron, collocVC_PreNoun, true) == 0)
                        //    {
                        //        successfulCollocPreference = true;
                        //    }
                        //}
                        if (nextVC_Noun != null)
                        {
                            XElement lastTokenOfVC_PostNoun =
                                (from token in nextVC_Noun.Descendants("token")
                                 where token.Attribute("pos").Value.StartsWith("V")
                                 select token).LastOrDefault();
                            if (lastTokenOfVC_PostNoun != null)
                            {
                                collocVC_PostNoun = lastTokenOfVC_PostNoun.Attribute("lemma").Value;
                                //Console.WriteLine(collocVC_PostNoun);
                                //Console.WriteLine(collocVC_PostPron);

                                if (String.Compare(collocVC_PostPron, collocVC_PostNoun, true) == 0)
                                {
                                    successfulCollocPreference = true;
                                }
                            }
                        }
                        //{
                        //    collocVC_PostNoun = nextVC_Noun.Descendants("token").Last().Attribute("lemma").Value;
                        //    Console.WriteLine(collocVC_PostNoun);
                        //    Console.WriteLine(collocVC_PostPron);
                        //    if (String.Compare(collocVC_PostPron, collocVC_PostNoun, true) == 0)
                        //    {
                        //        successfulCollocPreference = true;
                        //    }
                        //}
                    }



                    #endregion
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



                    //hier kommt alles rein, was Scores tatsächlich zuweist:
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                    #region AuswertungZuweisung

                    //#00 Definiteness & #12 Non-Candidates
                    #region Definiteness

                    //WARNUNG AUSGEBEN FALLS  > 1
                    if (determiners.Count() == 0)
                    {
                        indicators[0] = 0;
                        indicators[12] = 0;
                    }
                    else
                    {
                        foreach (XElement determiner in determiners)
                        {
                            if (definiteArticles.Contains(determiner.Value, StringComparer.CurrentCultureIgnoreCase))
                            {
                                indicators[0] = 1;
                                indicators[12] = 0;
                            }
                            else if (indefiniteArticles.Contains(determiner.Value, StringComparer.CurrentCultureIgnoreCase))
                            {
                                indicators[0] = 0;
                                indicators[12] = -1;
                            }
                            else
                            {
                                indicators[0] = 0;
                                indicators[12] = 0;
                            }
                        }
                    }

                    #endregion

                    //#01 Givenness
                    #region Givenness

                    if (candID.Equals(currSentFirstNP_ID))
                        indicators[1] = 1;
                    else
                        indicators[1] = 0;

                    #endregion

                    //#02 Domain Concept Preference
                    #region DomainConceptPreference

                    if (matchesDomainConcepts)
                        indicators[2] = 1;
                    else
                        indicators[2] = 0;

                    #endregion

                    ////#03 Verb Preference
                    //#region VerbPreference

                    //if (vcSelectedNPs.ToList().Contains(candidate.Attribute("id").Value))
                    //    indicators[3] = 1;
                    //else
                    //    indicators[3] = 0;

                    //#endregion

                    //#04 "Noun Phrase" Preference
                    //#region NounPhrasePreference

                    //if (ncSelectedNPs.ToList().Contains(candidate.Attribute("id").Value))
                    //    indicators[4] = 1;
                    //else
                    //    indicators[4] = 0;

                    //#endregion

                    //#05 Lexical Reiteration
                    //(reiterationCount - 1) verwenden, um Idee "Wiederholung" richtig zu modellieren
                    #region LexicalReiteration

                    if ((reiterationCount - 1) >= 2)
                        indicators[5] = 2;
                    else if ((reiterationCount - 1) == 1)
                        indicators[5] = 1;
                    else
                        indicators[5] = 0;

                    #endregion

                    //#06 Section Heading Preference
                    #region SectionHeadingPreference

                    if (containedInHeadHeadNCs)
                        indicators[6] = 1;
                    else
                        indicators[6] = 0;

                    #endregion

                    //#07 Collocation Pattern Preference
                    #region CollocationPatternPreference

                    if (successfulCollocPreference)
                        indicators[7] = 2;
                    else
                        indicators[7] = 0;

                    #endregion

                    //#08 Referential Distance
                    #region ReferentialDistance

                    if (candSentID_Int == pronSentID_Int)
                    {
                        if (clauseEnd > 0)
                        {
                            if (clauseStart < candID_Int && candID_Int < clauseEnd)
                                indicators[8] = 2;
                            else
                                indicators[8] = 1;
                        }
                        else
                        {
                            indicators[8] = 1;
                        }
                    }
                    else if (candSentID_Int == (pronSentID_Int - 1))
                        indicators[8] = 0;
                    else if (candSentID_Int == (pronSentID_Int - 2))
                    {
                        indicators[8] = -1;
                    }

                    #endregion

                    //#09 "Non-prepositional" Noun Phrases
                    #region NonPrepositionalNounPhrases

                    if (candidate.Attribute("prepositional").Value.Equals("True"))
                        indicators[9] = -1;
                    else
                        indicators[9] = 0;

                    #endregion

                    //#10 "Immediate Reference"
                    #region ImmediateReference

                    if (matchedIR &&
                        (candSentID_Int == pronSentID_Int) &&
                        (candID_Int == foundNCforIR))
                    {
                        indicators[10] = 1;
                    }
                    else
                    {
                        indicators[10] = 0;
                    }

                    #endregion

                    //#11 Antecedent-pointing Constructions
                    #region AntecedentPointingConstructions

                    if (focusedNPs.Contains("" + candID_Int))
                        indicators[11] = 1;
                    else
                        indicators[11] = 0;


                    #endregion

                    //#12 Non-Candidates
                    #region NonCandidates
                    //merged
                    #endregion

                    #endregion
                    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

                    //Candidate currentCandidate = new Candidate(pronID_Int, candID_Int, indicators);
                    //candidateNouns.Add(currentCandidate);

                    //foreach (int i in indicators)
                    //{
                    //    Console.Write(i + "\t");
                    //}

                    //Console.Write(pronID_Int + "\t");
                    //Console.Write(candID_Int + "\t");
                    //Console.Write(currentCandidate.Distance + "\t");
                    ////Console.Write(currentCandidate.Score + "\t");

                    //foreach (XElement candidateElement in candidate.Descendants())
                    //    Console.Write(candidateElement.Value + " ");
                    //Console.WriteLine();
                }

                //candidateNouns.Sort((Candidate C1, Candidate C2) => (C2.Score.CompareTo(C1.Score)));

                //if (candidateNouns.Count == 0)
                //{
                //    Console.WriteLine("%");
                //}
                //else
                //{
                //    int maxScore = candidateNouns.Max((Candidate C) => C.Score);
                //    List<Candidate> HighscoreCandidates = candidateNouns.TakeWhile((Candidate C) => C.Score == maxScore).ToList();

                //    Candidate selectedCandidate =
                //                (HighscoreCandidates.Count == 1) ?
                //                    HighscoreCandidates.First() :
                //                    Disambiguate(HighscoreCandidates);

                //    Console.WriteLine("Ausgewählter Kandidat (ID): " + selectedCandidate.CandidateID);
                //}

                Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
                Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            }

            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
            Console.WriteLine("----------------------------------------------------------------------------------------------------------------------------------------");
        }

        private static Candidate Disambiguate(List<Candidate> AmbiguousCandidates)
        {
            foreach (int i in new int[] { 10, 7, 3 })
            {
                int MaxIndicator = AmbiguousCandidates.Max(
                                    (Candidate C) => C.Indicators[i]);

                try
                {
                    return AmbiguousCandidates.Single(
                            (Candidate C) => C.Indicators[i] == MaxIndicator);
                }
                catch
                {
                    try
                    {
                        AmbiguousCandidates.RemoveAll(
                            (Candidate C) => C.Indicators[i] < MaxIndicator);
                    }
                    catch { }
                }
            };
            int MinDistance = AmbiguousCandidates.Min(
                                (Candidate C2) => C2.Distance);
            return AmbiguousCandidates.Single(
                    (Candidate C1) => C1.Distance == MinDistance);
        }

        private static void InitIntArray(int[] arr)
        {
            for (int i = 0; i < arr.Length; i++)
                arr[i] = -9;
        }
    }
}
